<template>
  <a-card :bordered="false">
    <div class="table-page-search-wrapper">
      <a-form layout="inline" :form="queryForm">
        <a-row :gutter="48">
          <a-col :md="8" :sm="24">
            <a-form-item label="登录名称">
              <a-input
                placeholder="登录名称"
                v-decorator="['userName', { initialValue: this.queryParam.userName }]"
                name="userName"
              />
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="昵称">
              <a-input
                placeholder="昵称"
                v-decorator="['nickName', { initialValue: this.queryParam.nickName }]"
                name="nickName"
              />
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="冻结状态">
              <a-select
                placeholder="请选择冻结状态"
                v-decorator="['enabled', { initialValue: this.queryParam.enabled }]"
              >
                <a-select-option value="">全部</a-select-option>
                <a-select-option value="1">未冻结</a-select-option>
                <a-select-option value="0">已冻结</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <template v-if="advanced">
            <a-col :md="11" :sm="24">
              <a-form-item label="创建日期">
                <a-range-picker
                  :ranges="{
                    今天: [moment().startOf('day'), moment()],
                    昨天: [
                      moment()
                        .startOf('day')
                        .subtract(1, 'days'),
                      moment()
                        .endOf('day')
                        .subtract(1, 'days')
                    ],
                    一周: [
                      moment()
                        .startOf('day')
                        .subtract(1, 'weeks'),
                      moment()
                    ],
                    两周: [
                      moment()
                        .startOf('day')
                        .subtract(2, 'weeks'),
                      moment()
                    ],
                    一个月: [
                      moment()
                        .startOf('day')
                        .subtract(1, 'months'),
                      moment()
                    ],
                    一年: [
                      moment()
                        .startOf('day')
                        .subtract(1, 'years'),
                      moment()
                    ]
                  }"
                  :showTime="{ format: 'HH:mm:ss' }"
                  format="YYYY/MM/DD HH:mm:ss"
                  @change="changeDateTime"
                />
              </a-form-item>
            </a-col>
          </template>
          <a-col :md="8" :sm="24">
            <span
              class="table-page-search-submitButtons"
              :style="(advanced && { float: 'right', overflow: 'hidden' }) || {}"
            >
              <a-button type="primary" @click="this.search">查询</a-button>
              <a-button style="margin-left: 8px" @click="resetForm">重置</a-button>
              <a @click="toggleAdvanced" style="margin-left: 8px">
                {{ advanced ? '收起' : '展开' }}
                <a-icon :type="advanced ? 'up' : 'down'" />
              </a>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>

    <div class="table-operator">
      <a-button type="primary" icon="plus" v-action:sys:user:add @click="add">新建</a-button>
      <a-button
        type="primary"
        :disabled="selectedRowKeys.length != 1"
        icon="edit"
        v-action:sys:user:update
        @click="edit()"
        >编辑</a-button
      >
      <a-button
        type="danger"
        :disabled="selectedRowKeys.length == 0"
        icon="delete"
        v-action:sys:user:delete
        @click="del"
        >删除</a-button
      >
      <a-button type="danger" :disabled="enabledStatus" icon="lock" v-action:sys:user:enabled @click="enabledUser(true)"
        >冻结</a-button
      >
      <a-button
        type="danger"
        :disabled="unEnabledStatus"
        icon="unlock"
        v-action:sys:user:unEnabled
        @click="enabledUser(false)"
        >解冻</a-button
      >
      <a-button type="danger" :disabled="selectedRowKeys.length == 0" v-action:sys:user:resetPassWord icon="rest" @click="changePassword"
        >重置密码</a-button
      >
    </div>
    <a-spin :spinning="loading">
      <s-table
        ref="table"
        size="middle"
        rowKey="id"
        :columns="columns"
        :data="loadData"
        bordered
        :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      >
        <span slot="sex" slot-scope="text">
          <a-tag :color="text == 1 ? 'blue' : 'red'">
            {{ text == 1 ? '男' : '女' }}
          </a-tag>
        </span>
        <span slot="enabled" slot-scope="text">
          <a-tag :color="!text ? 'red' : 'green'">
            {{ !text ? '是' : '否' }}
          </a-tag>
        </span>

        <span slot="action" slot-scope="text, record">
          <a href="javascript:;" @click="view(record.id)">查看</a>
          <span v-action:sys:user:update>
            <a-divider type="vertical" />
            <a href="javascript:;" @click="edit(record.id)">编辑</a>
          </span>
          <span v-action:sys:user:delete>
            <a-divider type="vertical" />
            <a href="javascript:;" @click="deletes(record.id)">删除</a>
          </span>
          <span v-action:sys:user:resetPassWord>
            <a-divider type="vertical" />
            <a href="javascript:;" @click="changePassWord(record.id, false)">重置密码</a>
          </span>
        </span>
      </s-table>
    </a-spin>
    <!--新增/修改/查看弹出层-->
    <a-modal
      :title="formDisabled ? '查看' : this.$isNull(this.formData) || this.$isNull(this.formData.id) ? '新增' : '更新'"
      :width="960"
      :visible="visible"
      :centered="true"
      :confirmLoading="loading"
      :maskClosable="false"
      :destroyOnClose="true"
      :keyboard="true"
      @cancel="visibleModal()"
    >
      <a-spin :spinning="loading">
        <a-form :form="form" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
          <a-row :gutter="24" style="display:none;">
            <a-col :span="24">
              <a-form-item label="主键">
                <a-input v-decorator="['id', { rules: [{ required: false }], initialValue: this.formData.id }]" />
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="登录名称">
                <a-input
                  :maxLength="20"
                  :disabled="!this.$isNull(this.formData) && !this.$isNull(this.formData.id)"
                  v-decorator="[
                    'userName',
                    {
                      rules: [
                        { required: true, message: '请输入登录名称' },
                        {
                          validator: (rule, value, callback) =>
                            this.validatorExistUserName(
                              rule,
                              value,
                              callback,
                              !this.$isNull(this.formData) && !this.$isNull(this.formData.id)
                            ),
                          trigger: 'blur'
                        }
                      ],
                      initialValue: this.formData.userName
                    }
                  ]"
                  placeholder="请输入登录名称"
                />
              </a-form-item>
            </a-col>
            <a-col :span="12" v-if="this.$isNull(this.formData.id)">
              <a-form-item label="登录密码">
                <a-input-password
                  :maxLength="16"
                  v-decorator="[
                    'password',
                    {
                      rules: [
                        { required: true, message: '请输入登录密码' },
                        { validator: validatorPassword, trigger: 'blur' }
                      ],
                      initialValue: this.formData.password
                    }
                  ]"
                  placeholder="请输入登录密码"
                />
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="昵称">
                <a-input
                  :maxLength="10"
                  :disabled="formDisabled"
                  v-decorator="[
                    'nickName',
                    { rules: [{ required: true, message: '请输入昵称' }], initialValue: this.formData.nickName }
                  ]"
                  placeholder="请输入昵称"
                />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="角色">
                <a-select
                  v-decorator="[
                    'roleIds',
                    {
                      rules: [{ required: true, message: '请选择角色' }],
                      initialValue: this.formData.roleIds
                    }
                  ]"
                  :disabled="formDisabled"
                  mode="multiple"
                  :showArrow="true"
                  :allowClear="true"
                  placeholder="请选择角色"
                  option-label-prop="label"
                >
                  <a-select-option :value="r.id" :label="r.name" v-for="r in roles" :key="r.id">
                    {{ r.name }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>

          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="手机号">
                <a-input
                  :disabled="formDisabled"
                  v-decorator="[
                    'phone',
                    {
                      rules: [
                        { required: false },
                        {
                          validator: (rule, value, callback) => this.validatorPhone(rule, value, callback),
                          trigger: 'blur'
                        }
                      ],
                      initialValue: this.formData.phone
                    }
                  ]"
                  placeholder="请输入手机号"
                />
              </a-form-item>
            </a-col>

            <a-col :span="12">
              <a-form-item label="性别">
                <a-select
                  :disabled="formDisabled"
                  v-decorator="[
                    'sex',
                    {
                      rules: [{ required: false, message: '请选择用户的性别' }],
                      initialValue: this.$isNull(this.formData.sex) ? '' : this.formData.sex + ''
                    }
                  ]"
                  placeholder="请选择用户的性别"
                >
                  <a-select-option value="1">男</a-select-option>
                  <a-select-option value="0">女</a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>

          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="所属部门">
                <tree
                  v-decorator="[
                    'deptId',
                    {
                      rules: [{ required: false, message: '请选择上级部门' }],
                      initialValue: this.formData.deptId
                    }
                  ]"
                  selectable
                  :blockNode="true"
                  :defaultExpandedKeys="[this.formData.deptId]"
                  :defaultSelectedKeys="[this.formData.deptId]"
                  :treeData="deptTree"
                  @select="this.deptSelect"
                  :replaceFields="{
                    title: 'name',
                    key: 'id'
                  }"
                >
                </tree>
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="描述">
                <a-textarea
                  allow-clear
                  :disabled="formDisabled"
                  :autoSize="{ minRows: 5, maxRows: 6 }"
                  :maxLength="150"
                  placeholder="描述"
                  v-decorator="[
                    'description',
                    { rules: [{ required: false }], initialValue: this.formData.description }
                  ]"
                />
              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      </a-spin>

      <template slot="footer">
        <a-button key="back" @click="visibleModal()">
          返回
        </a-button>
        <a-button key="submit" type="primary" v-show="!formDisabled" :loading="loading" @click="save">
          保存
        </a-button>
      </template>
    </a-modal>
  </a-card>
</template>

<script>
import moment from 'moment'
import { STable } from '@/components'
import { Tree } from 'ant-design-vue'
import { list, del, add, get, update, existUserName, enabledUser, resetPassWord } from '@/api/system/user/user'
import { deptTree } from '@/api/system/dept/dept'
import { allRole } from '@/api/system/role/role'

export default {
  name: 'User',
  components: {
    STable,
    Tree
  },
  data() {
    return {
      // 高级搜索 展开/关闭
      advanced: false,
      // 新增/修改用户弹出层
      visible: false,
      // 禁用表单所有元素
      formDisabled: false,
      // 用户 新增/编辑表单
      formData: {},
      // 数据表单
      form: this.$form.createForm(this),
      // 查询表单
      queryForm: this.$form.createForm(this),
      // 新增/编辑 弹出层加载
      loading: false,
      // 查询参数
      queryParam: {
        pageIndex: 1,
        pageSize: 10,
        userName: '',
        nickName: '',
        startCreateTime: '',
        endCreateTime: ''
      },
      // 列表字段表头
      columns: [
        {
          title: '登录名',
          dataIndex: 'userName',
          width: '12%'
        },
        {
          title: '昵称',
          dataIndex: 'nickName',
          width: '10%',
          ellipsis: true
        },
        {
          title: '部门',
          dataIndex: 'deptName',
          width: '12%',
          ellipsis: true
        },
        {
          title: '性别',
          dataIndex: 'sex',
          width: '6%',
          align: 'center',
          scopedSlots: { customRender: 'sex' }
        },
        {
          title: '冻结',
          dataIndex: 'enabled',
          width: '6%',
          align: 'center',
          scopedSlots: { customRender: 'enabled' }
        },
        {
          title: '手机号',
          dataIndex: 'phone',
          width: '13%'
        },
        {
          title: '描述',
          width: '20%',
          dataIndex: 'description',
          ellipsis: true
        },
        {
          title: '创建时间',
          dataIndex: 'createTime',
          width: '15%',
          ellipsis: true
        },
        {
          title: '更新时间',
          dataIndex: 'updateTime',
          width: '15%',
          ellipsis: true
        },
        {
          title: '操作',
          key: 'action',
          align: 'center',
          width: '15%',
          scopedSlots: { customRender: 'action' }
        }
      ],
      // 加载数据方法 必须为 Promise 对象
      loadData: parameter => this.list(parameter),
      selectedRowKeys: [],
      selectedRows: [],
      // 系统角色
      roles: [],
      // 用户所属部门
      deptTree: [],
      // 冻结按钮状态
      enabledStatus: true,
      // 解冻按钮状态
      unEnabledStatus: true
    }
  },
  methods: {
    moment,
    // 查询创建日期 切换日期
    changeDateTime(dates, dateStrings) {
      this.queryParam.startCreateTime = dateStrings[0]
      this.queryParam.endCreateTime = dateStrings[1]
    },
    // 重置表单
    resetForm() {
      this.queryForm.resetFields()
      this.search()
    },
    // 批量修改用户密码
    changePassword() {
      const _this = this
      this.$confirm({
        centered: true,
        content: h => (
          <div>
            确认重置当前选中的 <b style="color:red;">{this.selectedRowKeys.length}</b> 条数据?
          </div>
        ),
        onOk() {
          _this.changePassWord(_this.selectedRowKeys.join(','), true)
        },
        onCancel() {
          _this.search()
        },
        class: 'deleteConfirm'
      })
      console.log(this.selectedRowKeys.join(','))
    },
    // 重置用户密码
    changePassWord(id, reload) {
      resetPassWord(id)
        .then(res => {
          if (res.code !== 200) {
            this.$message.error(res.msg)
          } else {
            this.$message.success(res.msg)
            if (reload) {
              this.search()
            }
          }
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {})
    },
    // 校验用户名唯一
    validatorExistUserName(rule, value, callback, edit) {
      if (edit) {
        return callback()
      } else if (this.$isNull(value)) {
        return callback()
      } else if (this.$isNull(this.$trim(value))) {
        return callback(new Error('请输入登录名称'))
      } else {
        existUserName(value)
          .then(res => {
            if (res.data) {
              return callback(new Error('登录名称已存在'))
            }
          })
          .catch(err => {
            console.log(err)
          })
          .finally(() => {
            return callback()
          })
      }
    },
    //  检查手机号是否输入正确
    validatorPhone(rule, value, callback) {
      if (value != null && value !== '') {
        var reg = /^1[3456789]\d{9}$/
        if (!reg.test(value)) {
          callback(new Error('手机号格式不正确'))
        }
      }
      // 调用callback
      callback()
    },
    // 校验密码
    validatorPassword(rule, value, callback) {
      if (value != null && value !== '') {
        var reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/
        if (!reg.test(value)) {
          return callback(new Error('登录密码必须包含数字和字符串'))
        }
      }
      // 调用callback
      callback()
    },
    // 查询数据
    search() {
      this.$refs.table.refresh(true)
    },
    // 列表查询数据
    list(params) {
      let queryParam = {}
      this.queryForm.validateFields((errors, values) => {
        queryParam = {
          ...this.queryParam,
          ...params,
          ...values
        }
      })
      return list(queryParam)
        .then(res => {
          return res.data
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.onSelectChange([], [])
        })
    },
    handleChange(value, key, column, record) {
      record[column.dataIndex] = value
    },
    // 分页选择数据
    onSelectChange(selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedRows = selectedRows
    },
    toggleAdvanced() {
      this.advanced = !this.advanced
    },
    // 新增用户
    add() {
      this.visibleModal()
    },
    // 编辑用户
    edit(id) {
      this.visibleModal(this.$isNull(id) ? this.selectedRowKeys[0] : id, null, false)
    },
    // 保存表单
    save(e) {
      e.preventDefault()
      this.form.validateFields((err, values) => {
        if (!err) {
          this.loading = true
          let promise = null
          if (!this.$isNull(values.id)) {
            promise = update(values)
          } else {
            promise = add(values)
          }
          promise
            .then(res => {
              if (res.code !== 200) {
                this.$message.error(res.msg)
              } else {
                this.visibleModal(null, res.msg, false)
              }
            })
            .catch(err => {
              console.log(err)
            })
            .finally(() => {
              this.loading = false
            })
        }
      })
    },
    // 确认删除用户
    del() {
      const _this = this
      this.$confirm({
        centered: true,
        content: h => (
          <div>
            确认删除当前选中的 <b style="color:red;">{this.selectedRowKeys.length}</b> 条数据?
          </div>
        ),
        onOk() {
          _this.deletes(_this.selectedRowKeys.join(','))
        },
        onCancel() {
          _this.search()
        },
        class: 'deleteConfirm'
      })
    },
    // 删除数据
    deletes(ids) {
      del(ids)
        .then(res => {
          if (res.code !== 200) {
            this.$message.error(res.msg)
          } else {
            this.onSelectChange([], [])
          }
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.search()
        })
    },
    // 查看详情
    view(id) {
      this.visibleModal(id, null, true)
    },
    // 关闭新增/编辑/查看弹出层
    visibleModal(id, message, formDisabled) {
      if (this.visible) {
        this.search()
      } else {
        this.formData = {}
        this.loading = true
        this.formDisabled = this.$isNull(formDisabled) ? false : formDisabled
        allRole().then(res => {
          if (res.code !== 200) {
            this.$message.error(res.msg)
            return
          }
          this.roles = res.data
        })
        deptTree().then(res => {
          if (res.code !== 200) {
            this.$message.error(res.msg)
            return
          }
          this.deptTree = res.data
        })
      }

      if (this.$isNull(id)) {
        this.loading = false
        this.visible = !this.visible
      } else {
        get(id)
          .then(res => {
            if (res.code !== 200) {
              this.$message.error(res.msg)
              this.search()
              return
            }
            this.visible = !this.visible
            this.formData = this.$isNull(res.data) ? {} : res.data
            if (!this.$isNull(message)) {
              this.$message.success(message)
            }
          })
          .catch(err => {
            console.log(err)
          })
          .finally(() => {
            this.loading = false
          })
      }
    },
    // 选择部门
    deptSelect(selectedKeys, info) {
      this.form.setFieldsValue({
        deptId: selectedKeys[0]
      })
    },
    // 冻结用户
    enabledUser(enabled) {
      const _this = this
      this.$confirm({
        centered: true,
        content: h => (
          <div>
            确认{enabled ? '冻结' : '解冻'}当前选中的 <b style="color:red;">{this.selectedRowKeys.length}</b> 条数据?
          </div>
        ),
        onOk() {
          // _this.deletes(_this.selectedRowKeys.join(','))
          enabledUser(_this.selectedRowKeys.join(','), enabled)
            .then(res => {
              if (res.code !== 200) {
                _this.$message.error(res.msg)
              } else {
                _this.onSelectChange([], [])
              }
            })
            .catch(err => {
              console.log(err)
            })
            .finally(() => {
              _this.search()
            })
        },
        onCancel() {
          _this.search()
        },
        class: 'deleteConfirm'
      })
    },
    // 重置密码
    restPassword() {
      this.$confirm({
        centered: true,
        title: '请输入新的密码',
        content: h => (
          <div style="color:red;">
            <a-input-password placeholder="新密码" />
          </div>
        ),
        onOk() {
          console.log('OK')
        },
        onCancel() {
          console.log('Cancel')
        },
        class: 'test'
      })
    }
  },
  watch: {
    // 冻结/解冻
    selectedRows(rows) {
      if (this.$isNull(rows) || rows.length > 0) {
        var extEnabled = false
        var extUnEnabled = false
        for (var x = 0; x < rows.length; x++) {
          if (rows[x].enabled) {
            extUnEnabled = true
          } else {
            extEnabled = true
          }
        }
        this.enabledStatus = extEnabled
        this.unEnabledStatus = extUnEnabled
      } else {
        this.enabledStatus = true
        this.unEnabledStatus = true
      }
    }
  }
}
</script>

<style lang="less" scoped>
.search {
  margin-bottom: 54px;
}

.fold {
  width: calc(100% - 216px);
  display: inline-block;
}

.operator {
  margin-bottom: 18px;
}

@media screen and (max-width: 900px) {
  .fold {
    width: 100%;
  }
}
.ant-calendar-picker {
  width: 358px !important;
}
</style>
